import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
import java.text.*;
import java.util.*;
import java.util.List;
import java.util.stream.Collectors;

// 用户身份枚举
enum UserType {
    STUDENT, TEACHER
}

// 用户报名类型
enum EnrollmentType {
    PARTICIPANT, REFEREE, VOLUNTEER
}

// 运动会项目实体
class Project {
    String id, name, rule, location;
    Date startTime, endTime;

    List<User> participants = new ArrayList<>();
    List<User> referees = new ArrayList<>();
    List<User> volunteers = new ArrayList<>();

    Map<User, List<Score>> scoreMap = new HashMap<>();

    public Project(String id, String name, String rule, Date startTime, Date endTime, String location) {
        this.id = id;
        this.name = name;
        this.rule = rule;
        this.startTime = startTime;
        this.endTime = endTime;
        this.location = location;
    }

    public void addParticipant(User u) {
        if (!participants.contains(u)) participants.add(u);
    }

    public void addReferee(User u) {
        if (!referees.contains(u)) referees.add(u);
    }

    public void addVolunteer(User u) {
        if (!volunteers.contains(u)) volunteers.add(u);
    }

    public boolean addScore(User referee, User participant, int value) {
        if (!referees.contains(referee) || !participants.contains(participant)) return false;
        scoreMap.putIfAbsent(participant, new ArrayList<>());
        scoreMap.get(participant).add(new Score(referee, value));
        return true;
    }

    public int getTotalScore(User participant) {
        if (!scoreMap.containsKey(participant)) return 0;
        return scoreMap.get(participant).stream().mapToInt(s -> s.value).sum();
    }

    public List<User> getRanking() {
        return participants.stream()
                .sorted((a,b) -> Integer.compare(getTotalScore(b), getTotalScore(a)))
                .collect(Collectors.toList());
    }
}

// 用户实体
class User {
    String id, name;
    UserType type;

    public User(String id, String name, UserType type) {
        this.id = id;
        this.name = name;
        this.type = type;
    }

    public String toString() {
        return String.format("%s (%s)", name, id);
    }
}

// 评分实体
class Score {
    User referee;
    int value;

    public Score(User referee, int value) {
        this.referee = referee;
        this.value = value;
    }
}

// 运动会管理器（数据层）
class SportsManager {
    List<Project> projects = new ArrayList<>();
    Map<String, User> users = new HashMap<>();

    // 单例
    private static SportsManager instance;
    private SportsManager() {}
    public static SportsManager getInstance() {
        if (instance == null) instance = new SportsManager();
        return instance;
    }

    // 添加用户
    public void addUser(User u) {
        users.put(u.id, u);
    }
    public User getUserById(String id) {
        return users.get(id);
    }

    // 添加项目
    public void addProject(Project p) {
        projects.add(p);
    }
    public Project getProjectById(String id) {
        for(Project p : projects) if(p.id.equals(id)) return p;
        return null;
    }
    public List<Project> getAllProjects() {
        return projects;
    }
}

// 自定义圆角按钮，带阴影
class PinkButton extends JButton {
    public PinkButton(String text) {
        super(text);
        setForeground(Color.WHITE);
        setBackground(new Color(255, 105, 180));
        setFocusPainted(false);
        setFont(new Font("微软雅黑", Font.BOLD, 16));
        setBorder(new EmptyBorder(10, 25, 10, 25));
        setContentAreaFilled(false);
    }

    protected void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D) g.create();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // 阴影效果
        g2.setColor(new Color(255, 105, 180, 150));
        g2.fillRoundRect(4, 4, getWidth()-8, getHeight()-8, 20, 20);

        // 主按钮
        g2.setColor(getBackground());
        g2.fillRoundRect(0, 0, getWidth()-8, getHeight()-8, 20, 20);

        // 文字
        FontMetrics fm = g2.getFontMetrics();
        int x = (getWidth()-8 - fm.stringWidth(getText())) / 2;
        int y = (getHeight()-8 + fm.getAscent()) / 2 - 2;
        g2.setColor(getForeground());
        g2.drawString(getText(), x, y);

        g2.dispose();
    }
}

// 主界面
public class HenanSportsSystem extends JFrame {

    private SportsManager manager = SportsManager.getInstance();

    // 顶部Logo栏
    private JPanel topPanel;
    private JLabel lblLogo;

    // 中间功能区
    private JTabbedPane tabPane;

    // 发布项目面板
    private JPanel panelPublish;
    private JTextField tfProjectId, tfProjectName, tfRule, tfLocation;
    private JTextField tfStartTime, tfEndTime;  // 用文本输入，格式 yyyy-MM-dd HH:mm
    private PinkButton btnPublish;

    // 报名面板
    private JPanel panelEnroll;
    private JTextField tfUserId, tfUserName;
    private JComboBox<String> cbUserType, cbEnrollType, cbProjectEnroll;
    private PinkButton btnEnroll;
    private JTextArea taEnrollInfo;

    // 评分面板
    private JPanel panelScore;
    private JComboBox<String> cbProjectScore, cbReferee, cbParticipant;
    private JTextField tfScoreValue;
    private PinkButton btnAddScore;
    private JTextArea taScoreInfo;

    // 查询排名面板
    private JPanel panelRanking;
    private JComboBox<String> cbProjectRank;
    private PinkButton btnShowRank;
    private JTextArea taRankInfo;

    public HenanSportsSystem() {
        setTitle("河南工业大学运动会管理系统");
        setSize(850, 600);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLayout(new BorderLayout());

        // 顶部LOGO
        topPanel = new JPanel();
        topPanel.setBackground(new Color(255, 182, 193));
        lblLogo = new JLabel("🏅 河南工业大学运动会管理系统");
        lblLogo.setFont(new Font("微软雅黑", Font.BOLD, 26));
        lblLogo.setForeground(Color.WHITE);
        topPanel.add(lblLogo);
        add(topPanel, BorderLayout.NORTH);

        // Tab切换
        tabPane = new JTabbedPane();
        tabPane.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        add(tabPane, BorderLayout.CENTER);

        initPublishPanel();
        initEnrollPanel();
        initScorePanel();
        initRankingPanel();

        // 加载测试数据
        loadTestData();

        // 更新下拉框项目列表
        refreshProjectLists();
    }

    // 初始化“发布项目”面板
    private void initPublishPanel() {
        panelPublish = new JPanel(new GridBagLayout());
        panelPublish.setBackground(new Color(255, 228, 225));
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(10, 12, 10, 12);
        gbc.fill = GridBagConstraints.HORIZONTAL;

        // 左侧标签，右侧输入框对称居中
        String[] labels = {"项目ID:", "项目名称:", "规则:", "开始时间(yyyy-MM-dd HH:mm):", "结束时间(yyyy-MM-dd HH:mm):", "地点:"};
        JTextField[] fields = new JTextField[6];
        tfProjectId = new JTextField(15);
        tfProjectName = new JTextField(15);
        tfRule = new JTextField(15);
        tfStartTime = new JTextField(15);
        tfEndTime = new JTextField(15);
        tfLocation = new JTextField(15);

        JTextField[] inputs = {tfProjectId, tfProjectName, tfRule, tfStartTime, tfEndTime, tfLocation};

        for (int i = 0; i < labels.length; i++) {
            gbc.gridx = 0;
            gbc.gridy = i;
            gbc.anchor = GridBagConstraints.EAST;
            JLabel lbl = new JLabel(labels[i]);
            lbl.setFont(new Font("微软雅黑", Font.PLAIN, 14));
            panelPublish.add(lbl, gbc);

            gbc.gridx = 1;
            gbc.anchor = GridBagConstraints.WEST;
            inputs[i].setFont(new Font("微软雅黑", Font.PLAIN, 14));
            panelPublish.add(inputs[i], gbc);
        }

        // 发布按钮
        gbc.gridx = 0;
        gbc.gridy = labels.length;
        gbc.gridwidth = 2;
        gbc.anchor = GridBagConstraints.CENTER;
        btnPublish = new PinkButton("发布项目");
        panelPublish.add(btnPublish, gbc);

        btnPublish.addActionListener(e -> publishProject());

        tabPane.addTab("管理者发布项目", panelPublish);
    }

    // 发布项目处理
    private void publishProject() {
        String id = tfProjectId.getText().trim();
        String name = tfProjectName.getText().trim();
        String rule = tfRule.getText().trim();
        String start = tfStartTime.getText().trim();
        String end = tfEndTime.getText().trim();
        String location = tfLocation.getText().trim();

        if (id.isEmpty() || name.isEmpty() || rule.isEmpty() || start.isEmpty() || end.isEmpty() || location.isEmpty()) {
            JOptionPane.showMessageDialog(this, "请填写完整项目信息！", "错误", JOptionPane.ERROR_MESSAGE);
            return;
        }

        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
            Date startTime = sdf.parse(start);
            Date endTime = sdf.parse(end);

            Project p = new Project(id, name, rule, startTime, endTime, location);
            manager.addProject(p);

            JOptionPane.showMessageDialog(this, "项目发布成功！", "成功", JOptionPane.INFORMATION_MESSAGE);
            clearPublishForm();
            refreshProjectLists();

        } catch (Exception ex) {
            JOptionPane.showMessageDialog(this, "时间格式错误，请使用 yyyy-MM-dd HH:mm 格式", "错误", JOptionPane.ERROR_MESSAGE);
        }
    }

    private void clearPublishForm() {
        tfProjectId.setText("");
        tfProjectName.setText("");
        tfRule.setText("");
        tfStartTime.setText("");
        tfEndTime.setText("");
        tfLocation.setText("");
    }

    // 初始化报名面板
    private void initEnrollPanel() {
        panelEnroll = new JPanel(new GridBagLayout());
        panelEnroll.setBackground(new Color(255, 228, 225));
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(10, 15, 10, 15);
        gbc.fill = GridBagConstraints.HORIZONTAL;

        JLabel lblUserId = new JLabel("用户ID:");
        JLabel lblUserName = new JLabel("姓名:");
        JLabel lblUserType = new JLabel("身份:");
        JLabel lblEnrollType = new JLabel("报名类型:");
        JLabel lblProject = new JLabel("选择项目:");

        tfUserId = new JTextField(15);
        tfUserName = new JTextField(15);
        cbUserType = new JComboBox<>(new String[]{"学生", "老师"});
        cbEnrollType = new JComboBox<>(new String[]{"参赛", "裁判员", "志愿者"});
        cbProjectEnroll = new JComboBox<>();

        // 左右对称排列
        gbc.gridx = 0; gbc.gridy = 0; gbc.anchor = GridBagConstraints.EAST;
        panelEnroll.add(lblUserId, gbc);
        gbc.gridx = 1; gbc.anchor = GridBagConstraints.WEST;
        panelEnroll.add(tfUserId, gbc);

        gbc.gridx = 0; gbc.gridy = 1; gbc.anchor = GridBagConstraints.EAST;
        panelEnroll.add(lblUserName, gbc);
        gbc.gridx = 1; gbc.anchor = GridBagConstraints.WEST;
        panelEnroll.add(tfUserName, gbc);

        gbc.gridx = 0; gbc.gridy = 2; gbc.anchor = GridBagConstraints.EAST;
        panelEnroll.add(lblUserType, gbc);
        gbc.gridx = 1; gbc.anchor = GridBagConstraints.WEST;
        panelEnroll.add(cbUserType, gbc);

        gbc.gridx = 0; gbc.gridy = 3; gbc.anchor = GridBagConstraints.EAST;
        panelEnroll.add(lblEnrollType, gbc);
        gbc.gridx = 1; gbc.anchor = GridBagConstraints.WEST;
        panelEnroll.add(cbEnrollType, gbc);

        gbc.gridx = 0; gbc.gridy = 4; gbc.anchor = GridBagConstraints.EAST;
        panelEnroll.add(lblProject, gbc);
        gbc.gridx = 1; gbc.anchor = GridBagConstraints.WEST;
        panelEnroll.add(cbProjectEnroll, gbc);

        gbc.gridx = 0; gbc.gridy = 5; gbc.gridwidth = 2; gbc.anchor = GridBagConstraints.CENTER;
        btnEnroll = new PinkButton("报名");
        panelEnroll.add(btnEnroll, gbc);

        taEnrollInfo = new JTextArea(6, 45);
        taEnrollInfo.setEditable(false);
        taEnrollInfo.setLineWrap(true);
        taEnrollInfo.setWrapStyleWord(true);
        taEnrollInfo.setFont(new Font("微软雅黑", Font.PLAIN, 14));
        JScrollPane scrollPane = new JScrollPane(taEnrollInfo);

        gbc.gridy = 6; gbc.weightx = 1; gbc.weighty = 1;
        gbc.fill = GridBagConstraints.BOTH;
        panelEnroll.add(scrollPane, gbc);

        btnEnroll.addActionListener(e -> enrollUser());

        tabPane.addTab("报名系统", panelEnroll);
    }

    // 报名处理
    private void enrollUser() {
        String id = tfUserId.getText().trim();
        String name = tfUserName.getText().trim();
        String userTypeStr = (String) cbUserType.getSelectedItem();
        String enrollTypeStr = (String) cbEnrollType.getSelectedItem();
        String projectName = (String) cbProjectEnroll.getSelectedItem();

        if (id.isEmpty() || name.isEmpty() || projectName == null) {
            JOptionPane.showMessageDialog(this, "请填写完整报名信息！", "错误", JOptionPane.ERROR_MESSAGE);
            return;
        }

        UserType userType = userTypeStr.equals("学生") ? UserType.STUDENT : UserType.TEACHER;
        EnrollmentType enrollType = EnrollmentType.PARTICIPANT;
        if (enrollTypeStr.equals("裁判员")) enrollType = EnrollmentType.REFEREE;
        else if (enrollTypeStr.equals("志愿者")) enrollType = EnrollmentType.VOLUNTEER;

        User user = manager.getUserById(id);
        if (user == null) {
            user = new User(id, name, userType);
            manager.addUser(user);
        }

        Project proj = null;
        for (Project p : manager.getAllProjects()) {
            if (p.name.equals(projectName)) {
                proj = p;
                break;
            }
        }

        if (proj == null) {
            JOptionPane.showMessageDialog(this, "项目不存在！", "错误", JOptionPane.ERROR_MESSAGE);
            return;
        }

        // 老师不能报名参赛项目（根据需求）
        if (userType == UserType.TEACHER && enrollType == EnrollmentType.PARTICIPANT) {
            JOptionPane.showMessageDialog(this, "老师不能报名参赛项目！", "错误", JOptionPane.ERROR_MESSAGE);
            return;
        }

        switch (enrollType) {
            case PARTICIPANT -> proj.addParticipant(user);
            case REFEREE -> proj.addReferee(user);
            case VOLUNTEER -> proj.addVolunteer(user);
        }

        taEnrollInfo.setText(String.format("用户 %s 报名成功！\n项目: %s\n报名类型: %s",
                user.toString(), proj.name, enrollTypeStr));
    }

    // 初始化评分面板
    private void initScorePanel() {
        panelScore = new JPanel(new GridBagLayout());
        panelScore.setBackground(new Color(255, 228, 225));
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(10, 15, 10, 15);
        gbc.fill = GridBagConstraints.HORIZONTAL;

        JLabel lblProject = new JLabel("选择项目:");
        JLabel lblReferee = new JLabel("裁判员:");
        JLabel lblParticipant = new JLabel("参赛者:");
        JLabel lblScore = new JLabel("评分(0-100):");

        cbProjectScore = new JComboBox<>();
        cbReferee = new JComboBox<>();
        cbParticipant = new JComboBox<>();
        tfScoreValue = new JTextField(5);
        btnAddScore = new PinkButton("添加评分");
        taScoreInfo = new JTextArea(8, 45);
        taScoreInfo.setEditable(false);
        taScoreInfo.setLineWrap(true);
        taScoreInfo.setWrapStyleWord(true);
        taScoreInfo.setFont(new Font("微软雅黑", Font.PLAIN, 14));

        JScrollPane scrollPane = new JScrollPane(taScoreInfo);

        // 左右对称布局
        gbc.gridx = 0; gbc.gridy = 0; gbc.anchor = GridBagConstraints.EAST;
        panelScore.add(lblProject, gbc);
        gbc.gridx = 1; gbc.anchor = GridBagConstraints.WEST;
        panelScore.add(cbProjectScore, gbc);

        gbc.gridx = 0; gbc.gridy = 1; gbc.anchor = GridBagConstraints.EAST;
        panelScore.add(lblReferee, gbc);
        gbc.gridx = 1; gbc.anchor = GridBagConstraints.WEST;
        panelScore.add(cbReferee, gbc);

        gbc.gridx = 0; gbc.gridy = 2; gbc.anchor = GridBagConstraints.EAST;
        panelScore.add(lblParticipant, gbc);
        gbc.gridx = 1; gbc.anchor = GridBagConstraints.WEST;
        panelScore.add(cbParticipant, gbc);

        gbc.gridx = 0; gbc.gridy = 3; gbc.anchor = GridBagConstraints.EAST;
        panelScore.add(lblScore, gbc);
        gbc.gridx = 1; gbc.anchor = GridBagConstraints.WEST;
        panelScore.add(tfScoreValue, gbc);

        gbc.gridx = 0; gbc.gridy = 4; gbc.gridwidth = 2; gbc.anchor = GridBagConstraints.CENTER;
        panelScore.add(btnAddScore, gbc);

        gbc.gridy = 5; gbc.weightx = 1; gbc.weighty = 1; gbc.fill = GridBagConstraints.BOTH;
        panelScore.add(scrollPane, gbc);

        btnAddScore.addActionListener(e -> addScore());

        cbProjectScore.addActionListener(e -> refreshScoreLists());

        tabPane.addTab("裁判评分", panelScore);
    }

    // 添加评分处理
    private void addScore() {
        String projectName = (String) cbProjectScore.getSelectedItem();
        String refereeStr = (String) cbReferee.getSelectedItem();
        String participantStr = (String) cbParticipant.getSelectedItem();
        String scoreStr = tfScoreValue.getText().trim();

        if (projectName == null || refereeStr == null || participantStr == null || scoreStr.isEmpty()) {
            JOptionPane.showMessageDialog(this, "请完整填写评分信息！", "错误", JOptionPane.ERROR_MESSAGE);
            return;
        }

        try {
            int score = Integer.parseInt(scoreStr);
            if (score < 0 || score > 100) throw new NumberFormatException();

            Project proj = null;
            for (Project p : manager.getAllProjects()) {
                if (p.name.equals(projectName)) {
                    proj = p;
                    break;
                }
            }

            if (proj == null) {
                JOptionPane.showMessageDialog(this, "项目不存在！", "错误", JOptionPane.ERROR_MESSAGE);
                return;
            }

            User referee = manager.getUserById(refereeStr.split(" ")[0]);
            User participant = manager.getUserById(participantStr.split(" ")[0]);

            if (referee == null || participant == null) {
                JOptionPane.showMessageDialog(this, "用户不存在！", "错误", JOptionPane.ERROR_MESSAGE);
                return;
            }

            proj.addScore(referee, participant, score);

            taScoreInfo.setText(String.format("裁判 %s 给参赛者 %s 在项目 %s 中打了 %d 分",
                    referee.name, participant.name, projectName, score));
            tfScoreValue.setText("");

        } catch (NumberFormatException ex) {
            JOptionPane.showMessageDialog(this, "评分请输入 0-100 的整数！", "错误", JOptionPane.ERROR_MESSAGE);
        }
    }

    private void refreshProjectLists() {
        cbProjectEnroll.removeAllItems();
        cbProjectScore.removeAllItems();

        for (Project p : manager.getAllProjects()) {
            cbProjectEnroll.addItem(p.name);
            cbProjectScore.addItem(p.name);
        }

        refreshScoreLists();
    }

    private void refreshScoreLists() {
        cbReferee.removeAllItems();
        cbParticipant.removeAllItems();

        String projectName = (String) cbProjectScore.getSelectedItem();
        if (projectName == null) return;

        Project proj = null;
        for (Project p : manager.getAllProjects()) {
            if (p.name.equals(projectName)) {
                proj = p;
                break;
            }
        }

        if (proj == null) return;

        for (User referee : proj.getReferees()) {
            cbReferee.addItem(referee.id + " " + referee.name);
        }

        for (User participant : proj.getParticipants()) {
            cbParticipant.addItem(participant.id + " " + participant.name);
        }
    }
